odhcpd: remove OAF_BROKEN_HOSTNAME
authorDavid Härdeman <[email protected]>
Sun, 23 Nov 2025 23:05:33 +0000 (00:05 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Sun, 30 Nov 2025 16:00:14 +0000 (17:00 +0100)
A bool is quite a bit more ergonomic (as the diff for this commit
shows).

Signed-off-by: David Härdeman <[email protected]>
Link: https://github.com/openwrt/odhcpd/pull/331
Signed-off-by: Álvaro Fernández Rojas <[email protected]>
src/config.c
src/dhcpv4.c
src/dhcpv6-ia.c
src/odhcpd.c
src/odhcpd.h
src/statefiles.c
src/ubus.c

index f5773dca3db8cbdf2469f0b7a99becc29bbe5411..0e588b6f95a4ae5f91b294ae3eb5af3e46bdf592 100644 (file)
@@ -673,8 +673,11 @@ int config_set_lease_cfg_from_blobmsg(struct blob_attr *ba)
        }
 
        if ((c = tb[LEASE_CFG_ATTR_NAME])) {
+               if (!odhcpd_hostname_valid(blobmsg_get_string(c)))
+                       goto err;
+
                lease_cfg->hostname = strdup(blobmsg_get_string(c));
-               if (!lease_cfg->hostname || !odhcpd_valid_hostname(lease_cfg->hostname))
+               if (!lease_cfg->hostname)
                        goto err;
        }
 
@@ -1767,23 +1770,27 @@ static void lease_cfg_delete_dhcpv6_leases(struct lease_cfg *lease_cfg)
 
 static void lease_cfg_update_leases(struct lease_cfg *lease_cfg)
 {
-       struct dhcpv4_lease *a4 = lease_cfg->dhcpv4_lease;
+       struct dhcpv4_lease *lease4 = lease_cfg->dhcpv4_lease;
        struct dhcpv6_lease *lease6;
 
-       if (a4) {
-               free(a4->hostname);
-               a4->hostname = NULL;
+       if (lease4) {
+               free(lease4->hostname);
+               lease4->hostname = NULL;
 
-               if (lease_cfg->hostname)
-                       a4->hostname = strdup(lease_cfg->hostname);
+               if (lease_cfg->hostname) {
+                       lease4->hostname = strdup(lease_cfg->hostname);
+                       lease4->hostname_valid = true;
+               }
        }
 
        list_for_each_entry(lease6, &lease_cfg->dhcpv6_leases, lease_cfg_list) {
                free(lease6->hostname);
                lease6->hostname = NULL;
 
-               if (lease_cfg->hostname)
+               if (lease_cfg->hostname) {
                        lease6->hostname = strdup(lease_cfg->hostname);
+                       lease6->hostname_valid = true;
+               }
 
                lease6->leasetime = lease_cfg->leasetime;
        }
index 5afeb9183dbfa0807944747628ed97693a489f33..c41c13d6896af5fe11b935e7f95b7ea0ed92b1ef 100644 (file)
@@ -636,8 +636,10 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg req_msg, const uint8_t *re
                        if (lease_cfg) {
                                lease->flags |= OAF_STATIC;
 
-                               if (lease_cfg->hostname)
+                               if (lease_cfg->hostname) {
                                        lease->hostname = strdup(lease_cfg->hostname);
+                                       lease->hostname_valid = true;
+                               }
 
                                lease_cfg->dhcpv4_lease = lease;
                                lease->lease_cfg = lease_cfg;
@@ -667,11 +669,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg req_msg, const uint8_t *re
                                lease->hostname = new_name;
                                memcpy(lease->hostname, req_hostname, req_hostname_len);
                                lease->hostname[req_hostname_len] = 0;
-
-                               if (odhcpd_valid_hostname(lease->hostname))
-                                       lease->flags &= ~OAF_BROKEN_HOSTNAME;
-                               else
-                                       lease->flags |= OAF_BROKEN_HOSTNAME;
+                               lease->hostname_valid = odhcpd_hostname_valid(lease->hostname);
                        }
                }
 
index 34b088b47de8193d8f64f428b7ec46eb2fc3bc32..cc27e5b266de4b96e320373d18de411493fd855a 100644 (file)
@@ -1173,8 +1173,10 @@ proceed:
                                                if (lease_cfg && assigned) {
                                                        a->flags |= OAF_STATIC;
 
-                                                       if (lease_cfg->hostname)
+                                                       if (lease_cfg->hostname) {
                                                                a->hostname = strdup(lease_cfg->hostname);
+                                                               a->hostname_valid = true;
+                                                       }
 
                                                        if (lease_cfg->leasetime)
                                                                a->leasetime = lease_cfg->leasetime;
@@ -1244,11 +1246,7 @@ proceed:
                                                a->hostname = tmp;
                                                memcpy(a->hostname, hostname, hostname_len);
                                                a->hostname[hostname_len] = 0;
-
-                                               if (odhcpd_valid_hostname(a->hostname))
-                                                       a->flags &= ~OAF_BROKEN_HOSTNAME;
-                                               else
-                                                       a->flags |= OAF_BROKEN_HOSTNAME;
+                                               a->hostname_valid = odhcpd_hostname_valid(a->hostname);
                                        }
                                }
                                a->accept_fr_nonce = accept_reconf;
index 3ba94a288e20459a4880a6ac3fd1b4ea5e46f254..00ca42d7a9d016246468feb7a807ec3a85c0ce08 100644 (file)
@@ -756,14 +756,13 @@ int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *p
        return 0;
 }
 
-bool odhcpd_valid_hostname(const char *name)
+bool odhcpd_hostname_valid(const char *name)
 {
-#define MAX_LABEL      63
        const char *c, *label, *label_end;
        int label_sz = 0;
 
        for (c = name, label_sz = 0, label = name, label_end = name + strcspn(name, ".") - 1;
-                       *c && label_sz <= MAX_LABEL; c++) {
+                       *c && label_sz <= DNS_MAX_LABEL_LEN; c++) {
                if ((*c >= '0' && *c <= '9') ||
                    (*c >= 'A' && *c <= 'Z') ||
                    (*c >= 'a' && *c <= 'z')) {
@@ -771,6 +770,7 @@ bool odhcpd_valid_hostname(const char *name)
                        continue;
                }
 
+               /* FIXME: underscore is not allowed in RFC 1035, RFC 1123? */
                if ((*c == '_' || *c == '-') && c != label && c != label_end) {
                        label_sz++;
                        continue;
@@ -788,5 +788,5 @@ bool odhcpd_valid_hostname(const char *name)
                return false;
        }
 
-       return (label_sz && label_sz <= MAX_LABEL ? true : false);
+       return (label_sz && label_sz <= DNS_MAX_LABEL_LEN ? true : false);
 }
index 6265c9472301f6658f1b1130f2a5c737b1f16b35..d4b87cf9c669a7bd399f425316ca0675234611d8 100644 (file)
@@ -193,9 +193,8 @@ enum odhcpd_assignment_flags {
        OAF_TENTATIVE           = (1 << 0),
        OAF_BOUND               = (1 << 1),
        OAF_STATIC              = (1 << 2),
-       OAF_BROKEN_HOSTNAME     = (1 << 3),
-       OAF_DHCPV6_NA           = (1 << 4),
-       OAF_DHCPV6_PD           = (1 << 5),
+       OAF_DHCPV6_NA           = (1 << 3),
+       OAF_DHCPV6_PD           = (1 << 4),
 };
 
 /* 2-byte type + 128-byte DUID, RFC8415, §11.1 */
@@ -260,6 +259,7 @@ struct dhcpv4_lease {
        unsigned int flags;                     // OAF_*
        time_t valid_until;                     // CLOCK_MONOTONIC time, 0 = inf
        char *hostname;                         // client hostname
+       bool hostname_valid;                    // is the hostname one or more valid DNS labels?
        size_t hwaddr_len;                      // hwaddr length
        uint8_t hwaddr[ETH_ALEN];               // hwaddr (only MAC supported)
 
@@ -302,6 +302,7 @@ struct dhcpv6_lease {
        unsigned int flags;
        uint32_t leasetime;
        char *hostname;
+       bool hostname_valid;                    // is the hostname one or more valid DNS labels?
 
        uint32_t iaid;
        uint16_t duid_len;
@@ -565,7 +566,7 @@ typedef void (*odhcpd_enum_addr6_cb_t)(struct dhcpv6_lease *lease,
 void odhcpd_enum_addr6(struct interface *iface, struct dhcpv6_lease *lease,
                       time_t now, odhcpd_enum_addr6_cb_t func, void *arg);
 int odhcpd_parse_addr6_prefix(const char *str, struct in6_addr *addr, uint8_t *prefix);
-bool odhcpd_valid_hostname(const char *name);
+bool odhcpd_hostname_valid(const char *name);
 
 int config_parse_interface(void *data, size_t len, const char *iname, bool overwrite);
 struct lease_cfg *config_find_lease_cfg_by_duid_and_iaid(const uint8_t *duid,
index 0c82a6d7116a444266f9b4fa2730c5d9b43a416f..20664f6d26636b719a0239ea2733b5385bbaf5cd 100644 (file)
@@ -55,7 +55,7 @@ static bool statefiles_write_host6(struct write_ctxt *ctxt, struct dhcpv6_lease
 {
        char ipbuf[INET6_ADDRSTRLEN];
 
-       if (!lease->hostname || lease->flags & OAF_BROKEN_HOSTNAME || !(lease->flags & OAF_DHCPV6_NA))
+       if (!lease->hostname || !lease->hostname_valid || !(lease->flags & OAF_DHCPV6_NA))
                return false;
 
        if (ctxt->fp) {
@@ -78,7 +78,7 @@ static bool statefiles_write_host4(struct write_ctxt *ctxt, struct dhcpv4_lease
 {
        char ipbuf[INET_ADDRSTRLEN];
 
-       if (!lease->hostname || lease->flags & OAF_BROKEN_HOSTNAME)
+       if (!lease->hostname || !lease->hostname_valid)
                return false;
 
        if (ctxt->fp) {
@@ -165,7 +165,7 @@ static void statefiles_write_state6_addr(struct dhcpv6_lease *lease, struct in6_
        struct write_ctxt *ctxt = (struct write_ctxt *)arg;
        char ipbuf[INET6_ADDRSTRLEN];
 
-       if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME) && lease->flags & OAF_DHCPV6_NA) {
+       if (lease->hostname && lease->hostname_valid && lease->flags & OAF_DHCPV6_NA) {
                md5_hash(addr, sizeof(*addr), &ctxt->md5);
                md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5);
        }
@@ -188,8 +188,8 @@ static void statefiles_write_state6(struct write_ctxt *ctxt, struct dhcpv6_lease
                fprintf(ctxt->fp,
                        "# %s %s %x %s%s %" PRId64 " %" PRIx64 " %" PRIu8,
                        ctxt->iface->ifname, duidbuf, ntohl(lease->iaid),
-                       (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "",
-                       (lease->hostname ? lease->hostname : "-"),
+                       lease->hostname_valid ? "" : "broken\\x20",
+                       lease->hostname ? lease->hostname : "-",
                        (lease->valid_until > ctxt->now ?
                         (int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) :
                         (INFINITE_VALID(lease->valid_until) ? -1 : 0)),
@@ -210,7 +210,7 @@ static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease
        char hexhwaddr[sizeof(lease->hwaddr) * 2 + 1];
        char ipbuf[INET6_ADDRSTRLEN];
 
-       if (lease->hostname && !(lease->flags & OAF_BROKEN_HOSTNAME)) {
+       if (lease->hostname && lease->hostname_valid) {
                md5_hash(&lease->ipv4, sizeof(lease->ipv4), &ctxt->md5);
                md5_hash(lease->hostname, strlen(lease->hostname), &ctxt->md5);
        }
@@ -225,8 +225,8 @@ static void statefiles_write_state4(struct write_ctxt *ctxt, struct dhcpv4_lease
        fprintf(ctxt->fp,
                "# %s %s ipv4 %s%s %" PRId64 " %x 32 %s/32\n",
                ctxt->iface->ifname, hexhwaddr,
-               (lease->flags & OAF_BROKEN_HOSTNAME) ? "broken\\x20" : "",
-               (lease->hostname ? lease->hostname : "-"),
+               lease->hostname_valid ? "" : "broken\\x20",
+               lease->hostname ? lease->hostname : "-",
                (lease->valid_until > ctxt->now ?
                 (int64_t)(lease->valid_until - ctxt->now + ctxt->wall_time) :
                 (INFINITE_VALID(lease->valid_until) ? -1 : 0)),
index 2f2f2060ba46387365d8c71387d7a189df5e5918..eebedf0389f8f2d03d78e1b1293e79101833c9b8 100644 (file)
@@ -65,7 +65,7 @@ static int handle_dhcpv4_leases(struct ubus_context *ctx, _o_unused struct ubus_
                        if (c->flags & OAF_STATIC)
                                blobmsg_add_string(&b, NULL, "static");
 
-                       if (c->flags & OAF_BROKEN_HOSTNAME)
+                       if (!c->hostname_valid)
                                blobmsg_add_string(&b, NULL, "broken-hostname");
                        blobmsg_close_array(&b, m);